<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.12">
<meta name="author" content="Peter Dimov">
<title>Describe: A C&#43;&#43;14 Reflection Library</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment @import statement to use as custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite::before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:50%;border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<style>
pre.rouge table td { padding: 5px; }
pre.rouge table pre { margin: 0; }
pre.rouge .cm {
  color: #999988;
  font-style: italic;
}
pre.rouge .cp {
  color: #999999;
  font-weight: bold;
}
pre.rouge .c1 {
  color: #999988;
  font-style: italic;
}
pre.rouge .cs {
  color: #999999;
  font-weight: bold;
  font-style: italic;
}
pre.rouge .c, pre.rouge .ch, pre.rouge .cd, pre.rouge .cpf {
  color: #999988;
  font-style: italic;
}
pre.rouge .err {
  color: #a61717;
  background-color: #e3d2d2;
}
pre.rouge .gd {
  color: #000000;
  background-color: #ffdddd;
}
pre.rouge .ge {
  color: #000000;
  font-style: italic;
}
pre.rouge .gr {
  color: #aa0000;
}
pre.rouge .gh {
  color: #999999;
}
pre.rouge .gi {
  color: #000000;
  background-color: #ddffdd;
}
pre.rouge .go {
  color: #888888;
}
pre.rouge .gp {
  color: #555555;
}
pre.rouge .gs {
  font-weight: bold;
}
pre.rouge .gu {
  color: #aaaaaa;
}
pre.rouge .gt {
  color: #aa0000;
}
pre.rouge .kc {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kd {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kn {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kp {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kr {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kt {
  color: #445588;
  font-weight: bold;
}
pre.rouge .k, pre.rouge .kv {
  color: #000000;
  font-weight: bold;
}
pre.rouge .mf {
  color: #009999;
}
pre.rouge .mh {
  color: #009999;
}
pre.rouge .il {
  color: #009999;
}
pre.rouge .mi {
  color: #009999;
}
pre.rouge .mo {
  color: #009999;
}
pre.rouge .m, pre.rouge .mb, pre.rouge .mx {
  color: #009999;
}
pre.rouge .sa {
  color: #000000;
  font-weight: bold;
}
pre.rouge .sb {
  color: #d14;
}
pre.rouge .sc {
  color: #d14;
}
pre.rouge .sd {
  color: #d14;
}
pre.rouge .s2 {
  color: #d14;
}
pre.rouge .se {
  color: #d14;
}
pre.rouge .sh {
  color: #d14;
}
pre.rouge .si {
  color: #d14;
}
pre.rouge .sx {
  color: #d14;
}
pre.rouge .sr {
  color: #009926;
}
pre.rouge .s1 {
  color: #d14;
}
pre.rouge .ss {
  color: #990073;
}
pre.rouge .s, pre.rouge .dl {
  color: #d14;
}
pre.rouge .na {
  color: #008080;
}
pre.rouge .bp {
  color: #999999;
}
pre.rouge .nb {
  color: #0086B3;
}
pre.rouge .nc {
  color: #445588;
  font-weight: bold;
}
pre.rouge .no {
  color: #008080;
}
pre.rouge .nd {
  color: #3c5d5d;
  font-weight: bold;
}
pre.rouge .ni {
  color: #800080;
}
pre.rouge .ne {
  color: #990000;
  font-weight: bold;
}
pre.rouge .nf, pre.rouge .fm {
  color: #990000;
  font-weight: bold;
}
pre.rouge .nl {
  color: #990000;
  font-weight: bold;
}
pre.rouge .nn {
  color: #555555;
}
pre.rouge .nt {
  color: #000080;
}
pre.rouge .vc {
  color: #008080;
}
pre.rouge .vg {
  color: #008080;
}
pre.rouge .vi {
  color: #008080;
}
pre.rouge .nv, pre.rouge .vm {
  color: #008080;
}
pre.rouge .ow {
  color: #000000;
  font-weight: bold;
}
pre.rouge .o {
  color: #000000;
  font-weight: bold;
}
pre.rouge .w {
  color: #bbbbbb;
}
pre.rouge {
  background-color: #f8f8f8;
}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Describe: A C&#43;&#43;14 Reflection Library</h1>
<div class="details">
<span id="author" class="author">Peter Dimov</span><br>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#overview">Overview</a></li>
<li><a href="#enums">Describing Enumeration Types</a></li>
<li><a href="#classes">Describing Class Types</a>
<ul class="sectlevel2">
<li><a href="#classes_class_types_with_public_members">Class Types with Public Members</a></li>
<li><a href="#classes_class_types_with_protected_or_private_members">Class Types with Protected or Private Members</a></li>
<li><a href="#classes_retrieving_class_properties">Retrieving Class Properties</a></li>
<li><a href="#classes_overloaded_member_functions">Overloaded Member Functions</a></li>
</ul>
</li>
<li><a href="#examples">Usage Examples</a>
<ul class="sectlevel2">
<li><a href="#example_printing_enums_ct">Printing Enumerators with a Compile Time Loop</a></li>
<li><a href="#example_printing_enums_rt">Printing Enumerators with a Run Time Loop</a></li>
<li><a href="#example_enum_to_string">enum_to_string</a></li>
<li><a href="#example_string_to_enum">string_to_enum</a></li>
<li><a href="#example_print_function">Defining a Universal Print Function</a></li>
<li><a href="#example_to_json">Automatic Conversion to JSON</a></li>
<li><a href="#example_from_json">Automatic Conversion from JSON</a></li>
<li><a href="#example_serialization">Automatic Serialization</a></li>
<li><a href="#example_json_rpc">Automatic JSON RPC</a></li>
</ul>
</li>
<li><a href="#implementation">Implementation Features</a>
<ul class="sectlevel2">
<li><a href="#implementation_dependencies">Dependencies</a></li>
<li><a href="#implementation_supported_compilers">Supported Compilers</a></li>
<li><a href="#implementation_limitations">Limitations</a></li>
</ul>
</li>
<li><a href="#reference">Reference</a>
<ul class="sectlevel2">
<li><a href="#ref_boostdescribeenum_hpp">&lt;boost/describe/enum.hpp&gt;</a>
<ul class="sectlevel3">
<li><a href="#ref_boost_describe_enum">BOOST_DESCRIBE_ENUM</a></li>
<li><a href="#ref_boost_describe_nested_enum">BOOST_DESCRIBE_NESTED_ENUM</a></li>
<li><a href="#ref_boost_define_enum">BOOST_DEFINE_ENUM</a></li>
<li><a href="#ref_boost_define_enum_class">BOOST_DEFINE_ENUM_CLASS</a></li>
<li><a href="#ref_boost_define_fixed_enum">BOOST_DEFINE_FIXED_ENUM</a></li>
<li><a href="#ref_boost_define_fixed_enum_class">BOOST_DEFINE_FIXED_ENUM_CLASS</a></li>
</ul>
</li>
<li><a href="#ref_boostdescribeenumerators_hpp">&lt;boost/describe/enumerators.hpp&gt;</a>
<ul class="sectlevel3">
<li><a href="#ref_describe_enumeratorse">describe_enumerators&lt;E&gt;</a></li>
</ul>
</li>
<li><a href="#ref_boostdescribeclass_hpp">&lt;boost/describe/class.hpp&gt;</a>
<ul class="sectlevel3">
<li><a href="#ref_boost_describe_struct">BOOST_DESCRIBE_STRUCT</a></li>
<li><a href="#ref_boost_describe_class">BOOST_DESCRIBE_CLASS</a></li>
</ul>
</li>
<li><a href="#ref_boostdescribemodifiers_hpp">&lt;boost/describe/modifiers.hpp&gt;</a>
<ul class="sectlevel3">
<li><a href="#ref_modifiers">modifiers</a></li>
</ul>
</li>
<li><a href="#ref_boostdescribebases_hpp">&lt;boost/describe/bases.hpp&gt;</a>
<ul class="sectlevel3">
<li><a href="#ref_describe_basest_m">describe_bases&lt;T, M&gt;</a></li>
</ul>
</li>
<li><a href="#ref_boostdescribemembers_hpp">&lt;boost/describe/members.hpp&gt;</a>
<ul class="sectlevel3">
<li><a href="#ref_describe_memberst_m">describe_members&lt;T, M&gt;</a></li>
</ul>
</li>
<li><a href="#ref_boostdescribe_hpp">&lt;boost/describe.hpp&gt;</a></li>
</ul>
</li>
<li><a href="#copyright">Copyright and License</a></li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="overview">Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This library enables authors of user-defined types (enums, structs
and classes) to describe their enumerators, base classes, data members
and member functions. This information can later be queried by other
code portions, possibly written by a different author, using the
supplied primitives <code>describe_enumerators</code>, <code>describe_bases</code>, and
<code>describe_members</code>.</p>
</div>
<div class="paragraph">
<p>To learn how to describe enumeration types, see <a href="#enums">Describing Enumeration Types</a>.</p>
</div>
<div class="paragraph">
<p>To learn how to describe class types, including structs, see <a href="#classes">Describing Class Types</a>.</p>
</div>
<div class="paragraph">
<p>For examples how this functionality is useful, see <a href="#examples">Usage Examples</a>.</p>
</div>
<div class="paragraph">
<p>The purpose of the library is to establish a standard way of providing
these reflection abilities. Many existing libraries provide their own
way of describing enums or classes, but without a standard, code written by
different people cannot interoperate.</p>
</div>
<div class="paragraph">
<p>Eventually, one might hope for the primitives to end up in the C&#43;&#43; standard,
with the compiler automatically supplying the metadata necessary to describe
the types, making manual macro annotation unnecessary.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="enums">Describing Enumeration Types</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you have an enumeration type</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="n">E</span>
<span class="p">{</span>
    <span class="n">v1</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
    <span class="n">v2</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
    <span class="n">v3</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>you can add reflection metadata to it via the <code>BOOST_DESCRIBE_ENUM</code> macro:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="n">v3</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The macro is defined in <code>&lt;boost/describe/enum.hpp&gt;</code> and should be placed in
the same namespace as the enum.</p>
</div>
<div class="paragraph">
<p>If your enumerators don&#8217;t have initializers, instead of repeating them</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="n">E2</span> <span class="p">{</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span> <span class="p">};</span>
<span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E2</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>you can use the convenience macro</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">BOOST_DEFINE_ENUM</span><span class="p">(</span><span class="n">E2</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>which expands to the two previous lines.</p>
</div>
<div class="paragraph">
<p>For defining <code>enum class E2</code> instead, use <code>BOOST_DEFINE_ENUM_CLASS</code>. To add
an underlying type, i.e. <code>enum E3: int</code> or <code>enum class E4: unsigned char</code>,
use <code>BOOST_DEFINE_FIXED_ENUM</code> and <code>BOOST_DEFINE_FIXED_ENUM_CLASS</code>, respectively.</p>
</div>
<div class="paragraph">
<p>If your enumeration type is nested inside a class or a <code>struct</code>, use the
<code>BOOST_DESCRIBE_NESTED_ENUM</code> macro next to the <code>enum</code>, as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">X</span>
<span class="p">{</span>
<span class="nl">private:</span>

    <span class="k">enum</span> <span class="k">class</span> <span class="nc">E</span>
    <span class="p">{</span>
        <span class="n">v1</span><span class="p">,</span>
        <span class="n">v2</span>
    <span class="p">};</span>

    <span class="n">BOOST_DESCRIBE_NESTED_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">)</span>

<span class="nl">public:</span>

    <span class="c1">// ...</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Once an enumeration type <code>E</code> is annotated, one can use <code>describe_enumerators&lt;E&gt;</code>
to obtain a <em>descriptor list</em>. (<code>describe_enumerators</code> is defined in the
<code>boost::describe</code> namespace, in <code>&lt;boost/describe/enumerators.hpp&gt;</code>.)</p>
</div>
<div class="paragraph">
<p>A descriptor list is a type of the form <code>L&lt;D1, D2, &#8230;&#8203;, Dn&gt;</code>, where <code>L</code> is of
the form <code>template&lt;class&#8230;&#8203; T&gt; struct L {};</code> and <code>Di</code> is of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">Di</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="n">E</span> <span class="n">value</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">name</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>To <a href="#example_printing_enums_ct">iterate over the descriptor list</a>, you can
use <code>mp_for_each</code> from <a href="https://boost.org/libs/mp11">Mp11</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_enumerators</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">([](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

    <span class="n">std</span><span class="o">::</span><span class="n">printf</span><span class="p">(</span> <span class="s">"%s: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">D</span><span class="p">.</span><span class="n">value</span> <span class="p">);</span>

<span class="p">});</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="classes">Describing Class Types</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="classes_class_types_with_public_members">Class Types with Public Members</h3>
<div class="paragraph">
<p>If you have a <code>struct</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">X</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">m1</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">m2</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>use the <code>BOOST_DESCRIBE_STRUCT</code> macro to describe it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">m1</span><span class="p">,</span> <span class="n">m2</span><span class="p">))</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><code>BOOST_DESCRIBE_STRUCT</code> is defined in <code>&lt;boost/describe/class.hpp&gt;</code> and should
be placed in the same namespace as the <code>struct</code>.</p>
</div>
<div class="paragraph">
<p>It takes three arguments: the <code>struct</code> name, a list of base classes
(empty in our example), and a list of (public) members by name (this includes
both data members and member functions.)</p>
</div>
<div class="paragraph">
<p>Since <code>BOOST_DESCRIBE_STRUCT</code> is placed outside the type, it&#8217;s non-intrisive,
does not require access to the definition, and can therefore be used to describe
third-party types or types defined in system headers.</p>
</div>
</div>
<div class="sect2">
<h3 id="classes_class_types_with_protected_or_private_members">Class Types with Protected or Private Members</h3>
<div class="paragraph">
<p>To describe a class type, use the <code>BOOST_DESCRIBE_CLASS</code> macro instead, placing
it <em>inside the class</em>. This gives the macro access to the protected and private
members, but is intrusive and requires access to the definition.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">Y</span><span class="o">:</span> <span class="k">private</span> <span class="n">X</span>
<span class="p">{</span>
<span class="nl">public:</span>

    <span class="kt">int</span> <span class="n">m3</span><span class="p">;</span>

<span class="nl">protected:</span>

    <span class="kt">int</span> <span class="n">m4</span><span class="p">;</span>

<span class="nl">private:</span>

    <span class="kt">int</span> <span class="n">m5</span><span class="p">;</span>

<span class="nl">public:</span>

    <span class="kt">int</span> <span class="n">f</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>

<span class="nl">private:</span>

    <span class="n">BOOST_DESCRIBE_CLASS</span><span class="p">(</span><span class="n">Y</span><span class="p">,</span> <span class="p">(</span><span class="n">X</span><span class="p">),</span> <span class="p">(</span><span class="n">m3</span><span class="p">,</span> <span class="n">f</span><span class="p">),</span> <span class="p">(</span><span class="n">m4</span><span class="p">),</span> <span class="p">(</span><span class="n">m5</span><span class="p">))</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>It takes three member lists, for the public, protected, and private members.</p>
</div>
</div>
<div class="sect2">
<h3 id="classes_retrieving_class_properties">Retrieving Class Properties</h3>
<div class="paragraph">
<p>Once a type <code>T</code> is annotated, its properties can be retrieved via
<code>describe_bases&lt;T, M&gt;</code> and <code>describe_members&lt;T, M&gt;</code> (<code>M</code> is a bitmask of
modifiers such as <code>mod_public | mod_static | mod_function</code>).</p>
</div>
<div class="paragraph">
<p>These primitives are defined in namespace <code>boost::describe</code>, in the headers
<code>&lt;boost/describe/bases.hpp&gt;</code> and <code>&lt;boost/describe/members.hpp&gt;</code>, respectively.</p>
</div>
<div class="paragraph">
<p><code>describe_bases</code> takes the following possible modifiers: <code>mod_public</code>,
<code>mod_protected</code>, <code>mod_private</code>, or a bitwise-or combination of them. The
presence of <code>mod_public</code> includes the public bases in the result, its absence
excludes them. The other two modifiers work similarly.</p>
</div>
<div class="paragraph">
<p><code>describe_members</code> takes a bitwise-or combination of the following possible
modifiers: <code>mod_public</code>, <code>mod_protected</code>, <code>mod_private</code>, <code>mod_static</code>,
<code>mod_function</code>, <code>mod_inherited</code>, <code>mod_hidden</code>.</p>
</div>
<div class="paragraph">
<p>The access modifiers work the same as with <code>describe_bases</code>.</p>
</div>
<div class="paragraph">
<p>(For types annotated with <code>BOOST_DESCRIBE_STRUCT</code>, the protected and private
member lists will be empty.)</p>
</div>
<div class="paragraph">
<p>When <code>mod_static</code> is present, the static members are returned, otherwise
the nonstatic members are returned.</p>
</div>
<div class="paragraph">
<p>When <code>mod_function</code> is present, the member functions are returned, otherwise
the data members are returned.</p>
</div>
<div class="paragraph">
<p>When <code>mod_inherited</code> is present, members of base classes are also returned.</p>
</div>
<div class="paragraph">
<p>When <code>mod_hidden</code> is present, hidden inherited members are included. A member
of a base class is hidden when a derived class has a member of the same name.</p>
</div>
<div class="paragraph">
<p>For the above class <code>Y</code>, <code>describe_bases&lt;Y, mod_any_access&gt;</code> will return a
type list <code>L&lt;D1&gt;</code> containing a single base descriptor <code>D1</code> describing <code>X</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">D1</span>
<span class="p">{</span>
    <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="n">X</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="n">modifiers</span> <span class="o">=</span> <span class="n">mod_private</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><code>describe_members&lt;Y, mod_private&gt;</code> will return a type list <code>L&lt;D2&gt;</code> containing
the descriptor of the data member <code>Y::m5</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">D2</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">Y</span><span class="o">::*</span> <span class="n">pointer</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">Y</span><span class="o">::</span><span class="n">m5</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"m5"</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="n">modifiers</span> <span class="o">=</span> <span class="n">mod_private</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>For an example of how to use the base and data member descriptors, see
<a href="#example_print_function">Defining a Universal Print Function</a>.</p>
</div>
<div class="paragraph">
<p>For an example of how to use member function descriptors, see
<a href="#example_json_rpc">Automatic JSON RPC</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="classes_overloaded_member_functions">Overloaded Member Functions</h3>
<div class="paragraph">
<p>To describe an overloaded member function, you will need to resort to
a more complicated syntax, as simply listing its name (say, <code>f</code>) will make
the library attempt to form a member pointer with <code>&amp;X::f</code>, which would fail
because it&#8217;s not clear to which <code>f</code> this expression refers.</p>
</div>
<div class="paragraph">
<p>To disambiguate, precede the function name with the type of the function, in
parentheses, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">X</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">f</span><span class="p">();</span>
    <span class="kt">int</span> <span class="n">f</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
    <span class="kt">void</span> <span class="n">f</span><span class="p">(</span> <span class="kt">int</span> <span class="n">x</span> <span class="p">);</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span>
    <span class="p">(</span><span class="kt">int</span> <span class="p">())</span> <span class="n">f</span><span class="p">,</span>
    <span class="p">(</span><span class="kt">int</span> <span class="p">()</span> <span class="k">const</span><span class="p">)</span> <span class="n">f</span><span class="p">,</span>
    <span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="kt">int</span><span class="p">))</span> <span class="n">f</span>
<span class="p">))</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The type of the function is the same as its declaration, without the name.</p>
</div>
<div class="paragraph">
<p>Be sure to retain the space between the parenthesized function type and its name,
because omitting it will compile happily on GCC and Clang but will lead to
inscrutable errors on MSVC due to its nonstandard preprocessor.</p>
</div>
<div class="paragraph">
<p>Pay attention to the proper placement of the parentheses, because a mistake there
will also lead to hard to decipher compiler errors, on all compilers.</p>
</div>
<div class="paragraph">
<p>The same technique also works with <code>BOOST_DESCRIBE_CLASS</code>, and with static member
functions:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">Y</span>
<span class="p">{</span>
<span class="nl">public:</span>

    <span class="k">static</span> <span class="kt">void</span> <span class="n">f</span><span class="p">(</span> <span class="kt">int</span> <span class="n">x</span> <span class="p">);</span>
    <span class="k">static</span> <span class="kt">void</span> <span class="n">f</span><span class="p">(</span> <span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span> <span class="p">);</span>

    <span class="n">BOOST_DESCRIBE_CLASS</span><span class="p">(</span><span class="n">Y</span><span class="p">,</span> <span class="p">(),</span> <span class="p">((</span><span class="kt">void</span> <span class="p">(</span><span class="kt">int</span><span class="p">))</span> <span class="n">f</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">))</span> <span class="n">f</span><span class="p">),</span> <span class="p">(),</span> <span class="p">())</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The case where a member function and a static member function have the same name
and the same function type is currently not supported.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="examples">Usage Examples</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="example_printing_enums_ct">Printing Enumerators with a Compile Time Loop</h3>
<div class="paragraph">
<p>A simple example that just iterates over the enumerator
descriptors using <code>mp11::mp_for_each</code> and prints them.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;cstdio&gt;
</span>
<span class="k">enum</span> <span class="n">E</span>
<span class="p">{</span>
    <span class="n">v1</span> <span class="o">=</span> <span class="mi">11</span><span class="p">,</span>
    <span class="n">v2</span><span class="p">,</span>
    <span class="n">v3</span> <span class="o">=</span> <span class="mi">5</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="n">v3</span><span class="p">)</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_enumerators</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">([](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="n">std</span><span class="o">::</span><span class="n">printf</span><span class="p">(</span> <span class="s">"%s: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">D</span><span class="p">.</span><span class="n">value</span> <span class="p">);</span>

    <span class="p">});</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_printing_enums_rt">Printing Enumerators with a Run Time Loop</h3>
<div class="paragraph">
<p>This is similar to the previous example, but it first builds a
<code>std::array</code> with the values, and then iterates over it using
an ordinary <code>for</code> loop, instead of <code>mp_for_each</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;cstdio&gt;
#include &lt;array&gt;
</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">E</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">enum_descriptor</span>
<span class="p">{</span>
    <span class="n">E</span> <span class="n">value</span><span class="p">;</span>
    <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">E</span><span class="p">,</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span><span class="o">...</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">class</span> <span class="nc">L</span><span class="p">,</span> <span class="k">class</span><span class="o">...</span> <span class="nc">T</span><span class="p">&gt;</span>
  <span class="k">constexpr</span> <span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">enum_descriptor</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">T</span><span class="p">)</span><span class="o">&gt;</span>
    <span class="n">describe_enumerators_as_array_impl</span><span class="p">(</span> <span class="n">L</span><span class="o">&lt;</span><span class="n">T</span><span class="p">...</span><span class="o">&gt;</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span> <span class="p">{</span> <span class="p">{</span> <span class="n">T</span><span class="o">::</span><span class="n">value</span><span class="p">,</span> <span class="n">T</span><span class="o">::</span><span class="n">name</span> <span class="p">}...</span> <span class="p">}</span> <span class="p">};</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">E</span><span class="p">&gt;</span> <span class="k">constexpr</span> <span class="k">auto</span> <span class="nf">describe_enumerators_as_array</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">describe_enumerators_as_array_impl</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_enumerators</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">()</span> <span class="p">);</span>
<span class="p">}</span>

<span class="n">BOOST_DEFINE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="n">v3</span><span class="p">,</span> <span class="n">v4</span><span class="p">,</span> <span class="n">v5</span><span class="p">,</span> <span class="n">v6</span><span class="p">)</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">constexpr</span> <span class="k">auto</span> <span class="n">D</span> <span class="o">=</span> <span class="n">describe_enumerators_as_array</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">();</span>

    <span class="k">for</span><span class="p">(</span> <span class="k">auto</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="o">:</span> <span class="n">D</span> <span class="p">)</span>
    <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">printf</span><span class="p">(</span> <span class="s">"%s: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">x</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">x</span><span class="p">.</span><span class="n">value</span> <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_enum_to_string">enum_to_string</h3>
<div class="paragraph">
<p>This example shows a function that, given an enumerator
value, returns its name.</p>
</div>
<div class="paragraph">
<p>Providing <code>enum_to_string</code> in a library is made difficult
by the fact that the desired behavior when the passed value
does not correspond to a named enumerator varies depending
on the specific use case. But, since defining the function
is trivial when <code>describe_enumerators</code> is available, every
user can easily have his own.</p>
</div>
<div class="paragraph">
<p>This specific example elects to return <code>"(unnamed)"</code> when
the enum value doesn&#8217;t have a name.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">E</span><span class="p">&gt;</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="nf">enum_to_string</span><span class="p">(</span> <span class="n">E</span> <span class="n">e</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">r</span> <span class="o">=</span> <span class="s">"(unnamed)"</span><span class="p">;</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_enumerators</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="k">if</span><span class="p">(</span> <span class="n">e</span> <span class="o">==</span> <span class="n">D</span><span class="p">.</span><span class="n">value</span> <span class="p">)</span> <span class="n">r</span> <span class="o">=</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span><span class="p">;</span>

    <span class="p">});</span>

    <span class="k">return</span> <span class="n">r</span><span class="p">;</span>
<span class="p">}</span>

<span class="cp">#include &lt;iostream&gt;
</span>
<span class="k">enum</span> <span class="n">E</span>
<span class="p">{</span>
    <span class="n">v1</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span>
    <span class="n">v2</span><span class="p">,</span>
    <span class="n">v3</span> <span class="o">=</span> <span class="mi">11</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="n">v3</span><span class="p">)</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"E("</span> <span class="o">&lt;&lt;</span> <span class="n">v1</span> <span class="o">&lt;&lt;</span> <span class="s">"): "</span> <span class="o">&lt;&lt;</span> <span class="n">enum_to_string</span><span class="p">(</span> <span class="n">v1</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"E("</span> <span class="o">&lt;&lt;</span> <span class="mi">0</span> <span class="o">&lt;&lt;</span> <span class="s">"): "</span> <span class="o">&lt;&lt;</span> <span class="n">enum_to_string</span><span class="p">(</span> <span class="n">E</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_string_to_enum">string_to_enum</h3>
<div class="paragraph">
<p>The opposite of the previous example; returns an enumerator
value when given the enumerator name. The same problem exists
here with respect to the error handling strategy when the string
passed does not correspond to any enumerator name. This example
throws an exception.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;stdexcept&gt;
#include &lt;typeinfo&gt;
#include &lt;string&gt;
#include &lt;cstring&gt;
</span>
<span class="p">[[</span><span class="n">noreturn</span><span class="p">]]</span> <span class="kt">void</span> <span class="nf">throw_invalid_name</span><span class="p">(</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">type</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="p">(</span>
        <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span> <span class="s">"Invalid enumerator name '"</span> <span class="p">)</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">"' for enum type '"</span> <span class="o">+</span> <span class="n">type</span> <span class="o">+</span> <span class="s">"'"</span> <span class="p">);</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">E</span><span class="p">&gt;</span> <span class="n">E</span> <span class="nf">string_to_enum</span><span class="p">(</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="n">E</span> <span class="n">r</span> <span class="o">=</span> <span class="p">{};</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_enumerators</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">found</span> <span class="o">&amp;&amp;</span> <span class="n">std</span><span class="o">::</span><span class="n">strcmp</span><span class="p">(</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">name</span> <span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
        <span class="p">{</span>
            <span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
            <span class="n">r</span> <span class="o">=</span> <span class="n">D</span><span class="p">.</span><span class="n">value</span><span class="p">;</span>
        <span class="p">}</span>

    <span class="p">});</span>

    <span class="k">if</span><span class="p">(</span> <span class="n">found</span> <span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">r</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">else</span>
    <span class="p">{</span>
        <span class="n">throw_invalid_name</span><span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="k">typeid</span><span class="p">(</span> <span class="n">E</span> <span class="p">).</span><span class="n">name</span><span class="p">()</span> <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="cp">#include &lt;iostream&gt;
</span>
<span class="n">BOOST_DEFINE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="n">v3</span><span class="p">)</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">try</span>
    <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"v1: "</span> <span class="o">&lt;&lt;</span> <span class="n">string_to_enum</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span> <span class="s">"v1"</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"v2: "</span> <span class="o">&lt;&lt;</span> <span class="n">string_to_enum</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span> <span class="s">"v2"</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"v3: "</span> <span class="o">&lt;&lt;</span> <span class="n">string_to_enum</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span> <span class="s">"v3"</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"v4: "</span> <span class="o">&lt;&lt;</span> <span class="n">string_to_enum</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;</span><span class="p">(</span> <span class="s">"v4"</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">catch</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">exception</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">x</span> <span class="p">)</span>
    <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">x</span><span class="p">.</span><span class="n">what</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_print_function">Defining a Universal Print Function</h3>
<div class="paragraph">
<p>This example defines a universal <code>operator&lt;&lt;</code> that works on
any class or struct type that has been described with
<code>BOOST_DESCRIBE_STRUCT</code> or <code>BOOST_DESCRIBE_CLASS</code>.</p>
</div>
<div class="paragraph">
<p>It first prints the base classes, recursively, then prints
all the members.</p>
</div>
<div class="paragraph">
<p>(A C cast is used to access private base classes. This is
not as bad as it first appears, because we&#8217;re only inspecting
the base class by printing its members, and doing so should not
change its state and hence cannot violate its invariant.)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;ostream&gt;
</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="p">;</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">Bd</span> <span class="o">=</span> <span class="n">describe_bases</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">mod_any_access</span><span class="p">&gt;,</span>
    <span class="k">class</span> <span class="nc">Md</span> <span class="o">=</span> <span class="n">describe_members</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">mod_any_access</span><span class="o">&gt;&gt;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">ostream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&lt;&lt;</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">ostream</span> <span class="o">&amp;</span> <span class="n">os</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">t</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">"{"</span><span class="p">;</span>

    <span class="kt">bool</span> <span class="n">first</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span><span class="n">Bd</span><span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">first</span> <span class="p">)</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">", "</span><span class="p">;</span> <span class="p">}</span> <span class="n">first</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>

        <span class="k">using</span> <span class="n">B</span> <span class="o">=</span> <span class="k">typename</span> <span class="k">decltype</span><span class="p">(</span><span class="n">D</span><span class="p">)</span><span class="o">::</span><span class="n">type</span><span class="p">;</span>
        <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">B</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span><span class="n">t</span><span class="p">;</span>

    <span class="p">});</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span><span class="n">Md</span><span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">first</span> <span class="p">)</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">", "</span><span class="p">;</span> <span class="p">}</span> <span class="n">first</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>

        <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">"."</span> <span class="o">&lt;&lt;</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span> <span class="o">&lt;&lt;</span> <span class="s">" = "</span> <span class="o">&lt;&lt;</span> <span class="n">t</span><span class="p">.</span><span class="o">*</span><span class="n">D</span><span class="p">.</span><span class="n">pointer</span><span class="p">;</span>

    <span class="p">});</span>

    <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">"}"</span><span class="p">;</span>
    <span class="k">return</span> <span class="n">os</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="nc">X</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">m1</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">m1</span><span class="p">))</span>

<span class="k">struct</span> <span class="nc">Y</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">m2</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">Y</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">m2</span><span class="p">))</span>

<span class="k">class</span> <span class="nc">Z</span><span class="o">:</span> <span class="k">public</span> <span class="n">X</span><span class="p">,</span> <span class="k">private</span> <span class="n">Y</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">m1</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">m2</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>

    <span class="n">BOOST_DESCRIBE_CLASS</span><span class="p">(</span><span class="n">Z</span><span class="p">,</span> <span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">),</span> <span class="p">(),</span> <span class="p">(),</span> <span class="p">(</span><span class="n">m1</span><span class="p">,</span> <span class="n">m2</span><span class="p">))</span>
<span class="p">};</span>

<span class="cp">#include &lt;iostream&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">Z</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_to_json">Automatic Conversion to JSON</h3>
<div class="paragraph">
<p>This example defines a universal <code>tag_invoke</code> overload that
automatically converts an annotated struct to a
<a href="http://master.json.cpp.al">Boost.JSON</a> value by iterating
over the described public members and adding them to the return
<code>boost::json::object</code>.</p>
</div>
<div class="paragraph">
<p>The overload is defined in namespace <code>app</code> in order to apply
to all annotated classes also defined in <code>app</code>.</p>
</div>
<div class="paragraph">
<p>The presence of private members is taken as an indication that
a universal conversion is not suitable, so the overload is
disabled in this case using <code>std::enable_if_t</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;boost/json.hpp&gt;
#include &lt;type_traits&gt;
#include &lt;vector&gt;
#include &lt;map&gt;
</span>
<span class="k">namespace</span> <span class="n">app</span>
<span class="p">{</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">D1</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_members</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_public</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_protected</span><span class="p">&gt;,</span>
    <span class="k">class</span> <span class="nc">D2</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_members</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_private</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">En</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if_t</span><span class="o">&lt;</span><span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_empty</span><span class="o">&lt;</span><span class="n">D2</span><span class="o">&gt;::</span><span class="n">value</span><span class="o">&gt;</span> <span class="o">&gt;</span>

    <span class="kt">void</span> <span class="n">tag_invoke</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_from_tag</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">t</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="k">auto</span><span class="o">&amp;</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">v</span><span class="p">.</span><span class="n">emplace_object</span><span class="p">();</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span><span class="n">D1</span><span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="n">obj</span><span class="p">[</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span> <span class="p">]</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_from</span><span class="p">(</span> <span class="n">t</span><span class="p">.</span><span class="o">*</span><span class="n">D</span><span class="p">.</span><span class="n">pointer</span> <span class="p">);</span>

    <span class="p">});</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="nc">A</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">y</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>

<span class="k">struct</span> <span class="nc">B</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="n">v</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="n">m</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">m</span><span class="p">))</span>

<span class="p">}</span> <span class="c1">// namespace app</span>

<span class="cp">#include &lt;iostream&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">app</span><span class="o">::</span><span class="n">B</span> <span class="n">b</span><span class="p">{</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span> <span class="p">}</span> <span class="p">},</span> <span class="p">{</span> <span class="p">{</span> <span class="s">"k1"</span><span class="p">,</span> <span class="p">{</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span> <span class="p">}</span> <span class="p">},</span> <span class="p">{</span> <span class="s">"k2"</span><span class="p">,</span> <span class="p">{</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">};</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_from</span><span class="p">(</span> <span class="n">b</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_from_json">Automatic Conversion from JSON</h3>
<div class="paragraph">
<p>Like the previous example, but in the other direction. Defines
a <code>tag_invoke</code> overload that converts a <code>boost::json::value</code> to
an annotated struct.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;boost/json.hpp&gt;
#include &lt;type_traits&gt;
</span>
<span class="k">namespace</span> <span class="n">app</span>
<span class="p">{</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="kt">void</span> <span class="n">extract</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">object</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">obj</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span><span class="p">,</span> <span class="n">T</span> <span class="o">&amp;</span> <span class="n">value</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="n">value</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_to</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">obj</span><span class="p">.</span><span class="n">at</span><span class="p">(</span> <span class="n">name</span> <span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">D1</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_members</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_public</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_protected</span><span class="p">&gt;,</span>
    <span class="k">class</span> <span class="nc">D2</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_members</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_private</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">En</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if_t</span><span class="o">&lt;</span><span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_empty</span><span class="o">&lt;</span><span class="n">D2</span><span class="o">&gt;::</span><span class="n">value</span><span class="o">&gt;</span> <span class="o">&gt;</span>

    <span class="n">T</span> <span class="n">tag_invoke</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_to_tag</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">obj</span> <span class="o">=</span> <span class="n">v</span><span class="p">.</span><span class="n">as_object</span><span class="p">();</span>

    <span class="n">T</span> <span class="n">t</span><span class="p">{};</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span><span class="n">D1</span><span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="n">extract</span><span class="p">(</span> <span class="n">obj</span><span class="p">,</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">t</span><span class="p">.</span><span class="o">*</span><span class="n">D</span><span class="p">.</span><span class="n">pointer</span> <span class="p">);</span>

    <span class="p">});</span>

    <span class="k">return</span> <span class="n">t</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="nc">A</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">y</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>

<span class="p">}</span> <span class="c1">// namespace app</span>

<span class="cp">#include &lt;iostream&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span> <span class="n">jv</span><span class="p">{</span> <span class="p">{</span> <span class="s">"x"</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="s">"y"</span><span class="p">,</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">};</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"jv: "</span> <span class="o">&lt;&lt;</span> <span class="n">jv</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

    <span class="k">auto</span> <span class="n">a</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_to</span><span class="o">&lt;</span><span class="n">app</span><span class="o">::</span><span class="n">A</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">jv</span> <span class="p">);</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"a: { "</span> <span class="o">&lt;&lt;</span> <span class="n">a</span><span class="p">.</span><span class="n">x</span> <span class="o">&lt;&lt;</span> <span class="s">", "</span> <span class="o">&lt;&lt;</span> <span class="n">a</span><span class="p">.</span><span class="n">y</span> <span class="o">&lt;&lt;</span> <span class="s">" }"</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_serialization">Automatic Serialization</h3>
<div class="paragraph">
<p>This example defines a universal <code>serialize</code> function that
automatically adds <a href="https://boost.org/libs/serialization">Boost.Serialization</a>
support to annotated classes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#define _CRT_SECURE_NO_WARNINGS
</span>
<span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;boost/serialization/serialization.hpp&gt;
#include &lt;boost/serialization/base_object.hpp&gt;
#include &lt;boost/serialization/vector.hpp&gt;
#include &lt;boost/core/nvp.hpp&gt;
#include &lt;type_traits&gt;
#include &lt;cstdio&gt;
#include &lt;vector&gt;
</span>
<span class="k">namespace</span> <span class="n">app</span>
<span class="p">{</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Archive</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">D1</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_bases</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_public</span><span class="p">&gt;,</span>
    <span class="k">class</span> <span class="nc">D2</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_bases</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_protected</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_private</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">D3</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_members</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_public</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_protected</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">D4</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_members</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_private</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="k">class</span> <span class="nc">En</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if_t</span><span class="o">&lt;</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_empty</span><span class="o">&lt;</span><span class="n">D2</span><span class="o">&gt;::</span><span class="n">value</span> <span class="o">&amp;&amp;</span> <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_empty</span><span class="o">&lt;</span><span class="n">D4</span><span class="o">&gt;::</span><span class="n">value</span><span class="o">&gt;</span> <span class="o">&gt;</span>

    <span class="kt">void</span> <span class="n">serialize</span><span class="p">(</span> <span class="n">Archive</span> <span class="o">&amp;</span> <span class="n">ar</span><span class="p">,</span> <span class="n">T</span> <span class="o">&amp;</span> <span class="n">t</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">serialization</span><span class="o">::</span><span class="n">version_type</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="c1">// public bases: use base_object</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span><span class="n">D1</span><span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="k">using</span> <span class="n">B</span> <span class="o">=</span> <span class="k">typename</span> <span class="k">decltype</span><span class="p">(</span><span class="n">D</span><span class="p">)</span><span class="o">::</span><span class="n">type</span><span class="p">;</span>

        <span class="kt">char</span> <span class="n">name</span><span class="p">[</span> <span class="mi">32</span> <span class="p">];</span>
        <span class="n">std</span><span class="o">::</span><span class="n">sprintf</span><span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="s">"base.%d"</span><span class="p">,</span> <span class="o">++</span><span class="n">k</span> <span class="p">);</span>

        <span class="n">ar</span> <span class="o">&amp;</span> <span class="n">boost</span><span class="o">::</span><span class="n">make_nvp</span><span class="p">(</span> <span class="n">name</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">serialization</span><span class="o">::</span><span class="n">base_object</span><span class="o">&lt;</span><span class="n">B</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">t</span> <span class="p">)</span> <span class="p">);</span>

    <span class="p">});</span>

    <span class="c1">// public (and protected) members</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span><span class="n">D3</span><span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="n">ar</span> <span class="o">&amp;</span> <span class="n">boost</span><span class="o">::</span><span class="n">make_nvp</span><span class="p">(</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">t</span><span class="p">.</span><span class="o">*</span><span class="n">D</span><span class="p">.</span><span class="n">pointer</span> <span class="p">);</span>

    <span class="p">});</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="nc">A1</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">A1</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">x</span><span class="p">))</span>

<span class="k">struct</span> <span class="nc">A2</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">y</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">A2</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">y</span><span class="p">))</span>

<span class="k">struct</span> <span class="nc">B</span><span class="o">:</span> <span class="k">public</span> <span class="n">A1</span><span class="p">,</span> <span class="k">public</span> <span class="n">A2</span>
<span class="p">{</span>
    <span class="c1">// these constructors aren't needed in C++17</span>
    <span class="n">B</span><span class="p">()</span><span class="o">:</span> <span class="n">A1</span><span class="p">(),</span> <span class="n">A2</span><span class="p">()</span> <span class="p">{}</span>
    <span class="n">B</span><span class="p">(</span> <span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span> <span class="p">)</span><span class="o">:</span> <span class="n">A1</span><span class="p">{</span> <span class="n">x</span> <span class="p">},</span> <span class="n">A2</span><span class="p">{</span> <span class="n">y</span> <span class="p">}</span> <span class="p">{}</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="p">(</span><span class="n">A1</span><span class="p">,</span> <span class="n">A2</span><span class="p">),</span> <span class="p">())</span>

<span class="k">struct</span> <span class="nc">C</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">B</span><span class="o">&gt;</span> <span class="n">v</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">v</span><span class="p">))</span>

<span class="p">}</span> <span class="c1">// namespace app</span>

<span class="cp">#include &lt;boost/archive/xml_oarchive.hpp&gt;
#include &lt;boost/archive/xml_iarchive.hpp&gt;
#include &lt;boost/archive/text_oarchive.hpp&gt;
#include &lt;string&gt;
#include &lt;sstream&gt;
#include &lt;iostream&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">app</span><span class="o">::</span><span class="n">C</span> <span class="n">c1</span><span class="p">{</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span> <span class="p">}</span> <span class="p">}</span> <span class="p">};</span>

    <span class="n">std</span><span class="o">::</span><span class="n">ostringstream</span> <span class="n">os</span><span class="p">;</span>

    <span class="p">{</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">xml_oarchive</span> <span class="n">ar</span><span class="p">(</span> <span class="n">os</span> <span class="p">);</span>
        <span class="n">ar</span> <span class="o">&lt;&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">make_nvp</span><span class="p">(</span> <span class="s">"c1"</span><span class="p">,</span> <span class="n">c1</span> <span class="p">);</span>
    <span class="p">}</span>

    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">s</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">str</span><span class="p">();</span>

    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">s</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

    <span class="n">app</span><span class="o">::</span><span class="n">C</span> <span class="n">c2</span><span class="p">;</span>

    <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">istringstream</span> <span class="n">is</span><span class="p">(</span> <span class="n">s</span> <span class="p">);</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">xml_iarchive</span> <span class="n">ar</span><span class="p">(</span> <span class="n">is</span> <span class="p">);</span>
        <span class="n">ar</span> <span class="o">&gt;&gt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">make_nvp</span><span class="p">(</span> <span class="s">"c2"</span><span class="p">,</span> <span class="n">c2</span> <span class="p">);</span>
    <span class="p">}</span>

    <span class="p">{</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">text_oarchive</span> <span class="n">ar</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="p">);</span>
        <span class="n">ar</span> <span class="o">&lt;&lt;</span> <span class="n">c2</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_json_rpc">Automatic JSON RPC</h3>
<div class="paragraph">
<p>This example defines a generic <code>call</code> function that can be used to
invoke a member function by name, with the arguments passed in a
<a href="http://master.json.cpp.al">Boost.JSON</a> array. The result is returned
in a <code>boost::json::value</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/describe.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;boost/json.hpp&gt;
#include &lt;boost/type_traits.hpp&gt;
#include &lt;boost/utility/string_view.hpp&gt;
#include &lt;stdexcept&gt;
#include &lt;string&gt;
</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">C1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">C2</span><span class="p">,</span> <span class="k">class</span> <span class="nc">R</span><span class="p">,</span> <span class="k">class</span><span class="o">...</span> <span class="nc">A</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">...</span> <span class="n">I</span><span class="p">&gt;</span>
  <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span>
    <span class="nf">call_impl_</span><span class="p">(</span> <span class="n">C1</span> <span class="o">&amp;</span> <span class="n">c1</span><span class="p">,</span> <span class="n">R</span> <span class="p">(</span><span class="n">C2</span><span class="o">::*</span><span class="n">pmf</span><span class="p">)(</span><span class="n">A</span><span class="p">...),</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">array</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">args</span><span class="p">,</span>
      <span class="n">std</span><span class="o">::</span><span class="n">index_sequence</span><span class="o">&lt;</span><span class="n">I</span><span class="p">...</span><span class="o">&gt;</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_from</span><span class="p">(</span>
      <span class="p">(</span><span class="n">c1</span><span class="p">.</span><span class="o">*</span><span class="n">pmf</span><span class="p">)(</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value_to</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">remove_cv_ref_t</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">(</span> <span class="n">args</span><span class="p">[</span> <span class="n">I</span> <span class="p">]</span> <span class="p">)...</span> <span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">C1</span><span class="p">,</span> <span class="k">class</span> <span class="nc">C2</span><span class="p">,</span> <span class="k">class</span> <span class="nc">R</span><span class="p">,</span> <span class="k">class</span><span class="o">...</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span>
    <span class="nf">call_impl</span><span class="p">(</span> <span class="n">C1</span> <span class="o">&amp;</span> <span class="n">c1</span><span class="p">,</span> <span class="n">R</span> <span class="p">(</span><span class="n">C2</span><span class="o">::*</span><span class="n">pmf</span><span class="p">)(</span><span class="n">A</span><span class="p">...),</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">array</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">args</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span><span class="p">(</span> <span class="n">args</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">!=</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">A</span><span class="p">)</span> <span class="p">)</span>
    <span class="p">{</span>
        <span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">invalid_argument</span><span class="p">(</span> <span class="s">"Invalid number of arguments"</span> <span class="p">);</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">call_impl_</span><span class="p">(</span> <span class="n">c1</span><span class="p">,</span> <span class="n">pmf</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">index_sequence_for</span><span class="o">&lt;</span><span class="n">A</span><span class="p">...</span><span class="o">&gt;</span><span class="p">()</span> <span class="p">);</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">C</span><span class="p">&gt;</span>
  <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span>
    <span class="nf">call</span><span class="p">(</span> <span class="n">C</span> <span class="o">&amp;</span> <span class="n">c</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">string_view</span> <span class="n">method</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">args</span> <span class="p">)</span>
<span class="p">{</span>
    <span class="k">using</span> <span class="n">Fd</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">describe_members</span><span class="o">&lt;</span><span class="n">C</span><span class="p">,</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_public</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">describe</span><span class="o">::</span><span class="n">mod_function</span><span class="o">&gt;</span><span class="p">;</span>

    <span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="n">boost</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">value</span> <span class="n">result</span><span class="p">;</span>

    <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="o">::</span><span class="n">mp_for_each</span><span class="o">&lt;</span><span class="n">Fd</span><span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">D</span><span class="p">){</span>

        <span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">found</span> <span class="o">&amp;&amp;</span> <span class="n">method</span> <span class="o">==</span> <span class="n">D</span><span class="p">.</span><span class="n">name</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">result</span> <span class="o">=</span> <span class="n">call_impl</span><span class="p">(</span> <span class="n">c</span><span class="p">,</span> <span class="n">D</span><span class="p">.</span><span class="n">pointer</span><span class="p">,</span> <span class="n">args</span><span class="p">.</span><span class="n">as_array</span><span class="p">()</span> <span class="p">);</span>
            <span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
        <span class="p">}</span>

    <span class="p">});</span>

    <span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">found</span> <span class="p">)</span>
    <span class="p">{</span>
        <span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">invalid_argument</span><span class="p">(</span> <span class="s">"Invalid method name"</span> <span class="p">);</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="nc">Object</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">greet</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="k">const</span> <span class="o">&amp;</span> <span class="n">who</span> <span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="s">"Hello, "</span> <span class="o">+</span> <span class="n">who</span> <span class="o">+</span> <span class="s">"!"</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kt">int</span> <span class="n">add</span><span class="p">(</span> <span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span> <span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">Object</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(</span><span class="n">greet</span><span class="p">,</span> <span class="n">add</span><span class="p">))</span>

<span class="cp">#include &lt;iostream&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">Object</span> <span class="n">obj</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">call</span><span class="p">(</span> <span class="n">obj</span><span class="p">,</span> <span class="s">"greet"</span><span class="p">,</span> <span class="p">{</span> <span class="s">"world"</span> <span class="p">}</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">call</span><span class="p">(</span> <span class="n">obj</span><span class="p">,</span> <span class="s">"add"</span><span class="p">,</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="implementation">Implementation Features</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="implementation_dependencies">Dependencies</h3>
<div class="paragraph">
<p><a href="https://boost.org/libs/mp11">Boost.Mp11</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="implementation_supported_compilers">Supported Compilers</h3>
<div class="ulist">
<ul>
<li>
<p>GCC 5 or later with <code>-std=c++14</code> or above</p>
</li>
<li>
<p>Clang 3.6 or later with <code>-std=c++14</code> or above</p>
</li>
<li>
<p>Visual Studio 2015, 2017, 2019</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Tested on <a href="https://travis-ci.org/github/pdimov/describe">Travis</a> and
<a href="https://ci.appveyor.com/project/pdimov/describe">Appveyor</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="implementation_limitations">Limitations</h3>
<div class="paragraph">
<p>This implementation has the following limitations:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Up to 52 elements are supported in the lists of enumerators,
bases, and members.</p>
</li>
<li>
<p>Protected base classes cannot be distinguished from private
base classes when the described class is final, and are considered
private.</p>
</li>
<li>
<p>Bitfields are not supported. It&#8217;s not possible to form a pointer
to member to a bitfield.</p>
</li>
<li>
<p>Reference members are not supported. It&#8217;s not possible to form a
pointer to member to a reference.</p>
</li>
<li>
<p>Anonymous unions are not supported.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reference">Reference</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="ref_boostdescribeenum_hpp">&lt;boost/describe/enum.hpp&gt;</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#define BOOST_DESCRIBE_ENUM(E, ...) </span><span class="cm">/*...*/</span><span class="cp">
</span>
<span class="cp">#define BOOST_DESCRIBE_NESTED_ENUM(E, ...) </span><span class="cm">/*...*/</span><span class="cp">
</span>
<span class="cp">#define BOOST_DEFINE_ENUM(E, ...) \
    enum E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__)
</span>
<span class="cp">#define BOOST_DEFINE_ENUM_CLASS(E, ...) \
    enum class E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM_CLASS(E, __VA_ARGS__)
</span>
<span class="cp">#define BOOST_DEFINE_FIXED_ENUM(E, Base, ...) \
    enum E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__)
</span>
<span class="cp">#define BOOST_DEFINE_FIXED_ENUM_CLASS(E, Base, ...) \
    enum class E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM_CLASS(E, __VA_ARGS__)</span></code></pre>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_describe_enum">BOOST_DESCRIBE_ENUM</h4>
<div class="paragraph">
<p><code>BOOST_DESCRIBE_ENUM(E, v1, v2, &#8230;&#8203;, vN)</code> should be placed in the namespace
where the enumeration type <code>E</code> is defined, and creates the necessary metadata
for <code>describe_enumerators&lt;E&gt;</code> to work.</p>
</div>
<div class="paragraph">
<p>After this macro is used, <code>describe_enumerators&lt;E&gt;</code> returns <code>L&lt;D1, D2, &#8230;&#8203;, Dn&gt;</code>,
where <code>L</code> is a class template of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span><span class="o">...</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">L</span> <span class="p">{};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>and <code>Di</code> is an <em>enumerator descriptor</em> of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">Di</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="n">E</span> <span class="n">value</span> <span class="o">=</span> <span class="n">vi</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"vi"</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>where <code>vi</code> is the corresponding identifier passed to the macro.</p>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_describe_nested_enum">BOOST_DESCRIBE_NESTED_ENUM</h4>
<div class="paragraph">
<p><code>BOOST_DESCRIBE_NESTED_ENUM(E, v1, v2, &#8230;&#8203;, vN)</code> is similar to
<code>BOOST_DESCRIBE_ENUM</code> and is used to annotate enumeration types nested inside
class (or <code>struct</code>) types. It should be placed in the class type where the
<code>enum</code> is defined.</p>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_define_enum">BOOST_DEFINE_ENUM</h4>
<div class="paragraph">
<p><code>BOOST_DEFINE_ENUM(E, v1, v2, &#8230;&#8203;, vN)</code> is a convenience macro expanding to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="n">E</span> <span class="p">{</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span> <span class="p">};</span>
<span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span><span class="p">)</span></code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_define_enum_class">BOOST_DEFINE_ENUM_CLASS</h4>
<div class="paragraph">
<p><code>BOOST_DEFINE_ENUM_CLASS(E, v1, v2, &#8230;&#8203;, vN)</code> is a convenience macro expanding to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="k">class</span> <span class="nc">E</span> <span class="p">{</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span> <span class="p">};</span>
<span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span><span class="p">)</span></code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_define_fixed_enum">BOOST_DEFINE_FIXED_ENUM</h4>
<div class="paragraph">
<p><code>BOOST_DEFINE_FIXED_ENUM(E, Base, v1, v2, &#8230;&#8203;, vN)</code> is a convenience macro expanding to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="n">E</span><span class="o">:</span> <span class="n">Base</span> <span class="p">{</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span> <span class="p">};</span>
<span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span><span class="p">)</span></code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_define_fixed_enum_class">BOOST_DEFINE_FIXED_ENUM_CLASS</h4>
<div class="paragraph">
<p><code>BOOST_DEFINE_FIXED_ENUM_CLASS(E, Base, v1, v2, &#8230;&#8203;, vN)</code> is a convenience macro expanding to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="k">class</span> <span class="nc">E</span><span class="o">:</span> <span class="n">Base</span> <span class="p">{</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span> <span class="p">};</span>
<span class="n">BOOST_DESCRIBE_ENUM</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="p">...,</span> <span class="n">vN</span><span class="p">)</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_boostdescribeenumerators_hpp">&lt;boost/describe/enumerators.hpp&gt;</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">describe</span> <span class="p">{</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">E</span><span class="p">&gt;</span> <span class="k">using</span> <span class="n">describe_enumerators</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span>

<span class="p">}</span> <span class="p">}</span></code></pre>
</div>
</div>
<div class="sect3">
<h4 id="ref_describe_enumeratorse">describe_enumerators&lt;E&gt;</h4>
<div class="paragraph">
<p><code>describe_enumerators&lt;E&gt;</code> returns <code>L&lt;D1, D2, &#8230;&#8203;, Dn&gt;</code>, where <code>L</code> is a class
template of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span><span class="o">...</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">L</span> <span class="p">{};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>and <code>Di</code> is an <em>enumerator descriptor</em> of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">Di</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="n">E</span> <span class="n">value</span> <span class="o">=</span> <span class="n">vi</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"vi"</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>where <code>vi</code> is the i-th enumerator.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_boostdescribeclass_hpp">&lt;boost/describe/class.hpp&gt;</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#define BOOST_DESCRIBE_STRUCT(Name, Bases, Members) </span><span class="cm">/*...*/</span><span class="cp">
#define BOOST_DESCRIBE_CLASS(Name, Bases, Public, Protected, Private) </span><span class="cm">/*...*/</span></code></pre>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_describe_struct">BOOST_DESCRIBE_STRUCT</h4>
<div class="paragraph">
<p><code>BOOST_DESCRIBE_STRUCT</code> should be placed in the same namespace as the struct
type being described, and takes three arguments: name of the struct type,
a parentheses-enclosed list of base classes, and a parentheses-enclosed list
of public members.</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">X</span>
<span class="p">{</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="p">(),</span> <span class="p">())</span>

<span class="k">struct</span> <span class="nc">Y</span><span class="o">:</span> <span class="k">public</span> <span class="n">X</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">m</span><span class="p">;</span>
    <span class="k">static</span> <span class="kt">void</span> <span class="n">f</span><span class="p">();</span>
<span class="p">};</span>

<span class="n">BOOST_DESCRIBE_STRUCT</span><span class="p">(</span><span class="n">Y</span><span class="p">,</span> <span class="p">(</span><span class="n">X</span><span class="p">),</span> <span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span></code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_boost_describe_class">BOOST_DESCRIBE_CLASS</h4>
<div class="paragraph">
<p><code>BOOST_DESCRIBE_CLASS</code> should be placed inside the class definition of the
described type, and takes five arguments: the name of the class, a list of
base classes, a list of public members, a list of protected members, and a
list of private members.</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">X</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">m1</span><span class="p">;</span>

    <span class="n">BOOST_DESCRIBE_CLASS</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="p">(),</span> <span class="p">(),</span> <span class="p">(),</span> <span class="p">(</span><span class="n">m1</span><span class="p">))</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Y</span><span class="o">:</span> <span class="k">private</span> <span class="n">X</span>
<span class="p">{</span>
<span class="nl">public:</span>

    <span class="kt">int</span> <span class="n">m1</span><span class="p">;</span>
    <span class="kt">void</span> <span class="n">f</span><span class="p">()</span> <span class="k">const</span> <span class="p">{}</span>

<span class="nl">protected:</span>

    <span class="kt">int</span> <span class="n">m2</span><span class="p">;</span>

<span class="nl">private:</span>

    <span class="kt">int</span> <span class="n">m3</span><span class="p">;</span>

    <span class="n">BOOST_DESCRIBE_CLASS</span><span class="p">(</span><span class="n">Y</span><span class="p">,</span> <span class="p">(</span><span class="n">X</span><span class="p">),</span> <span class="p">(</span><span class="n">m1</span><span class="p">,</span> <span class="n">f</span><span class="p">),</span> <span class="p">(</span><span class="n">m2</span><span class="p">),</span> <span class="p">(</span><span class="n">m3</span><span class="p">))</span>
<span class="p">};</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_boostdescribemodifiers_hpp">&lt;boost/describe/modifiers.hpp&gt;</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span>
<span class="p">{</span>
<span class="k">namespace</span> <span class="n">describe</span>
<span class="p">{</span>

<span class="k">enum</span> <span class="n">modifiers</span>
<span class="p">{</span>
    <span class="n">mod_public</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
    <span class="n">mod_protected</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
    <span class="n">mod_private</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span>
    <span class="n">mod_virtual</span> <span class="o">=</span> <span class="mi">8</span><span class="p">,</span>
    <span class="n">mod_static</span> <span class="o">=</span> <span class="mi">16</span><span class="p">,</span>
    <span class="n">mod_function</span> <span class="o">=</span> <span class="mi">32</span><span class="p">,</span>
    <span class="n">mod_inherited</span> <span class="o">=</span> <span class="mi">64</span><span class="p">,</span>
    <span class="n">mod_hidden</span> <span class="o">=</span> <span class="mi">128</span><span class="p">,</span>
<span class="p">};</span>

<span class="k">constexpr</span> <span class="n">modifiers</span> <span class="n">mod_any_access</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">modifiers</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">mod_public</span> <span class="o">|</span> <span class="n">mod_protected</span> <span class="o">|</span> <span class="n">mod_private</span> <span class="p">);</span>

<span class="p">}</span> <span class="c1">// namespace describe</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect3">
<h4 id="ref_modifiers">modifiers</h4>
<div class="paragraph">
<p>The enumeration type <code>modifiers</code> is a bitmask type that contains the
following flags:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>mod_public</code> - includes public bases or members in the descriptor list</p>
</li>
<li>
<p><code>mod_protected</code> - includes protected bases or members</p>
</li>
<li>
<p><code>mod_private</code> - includes private bases or members</p>
</li>
<li>
<p><code>mod_virtual</code> - returned when a base class is a virtual base</p>
</li>
<li>
<p><code>mod_static</code> - returns static members (when not given, returns nonstatic members)</p>
</li>
<li>
<p><code>mod_function</code> - returns member functions (when not given, returns data members)</p>
</li>
<li>
<p><code>mod_inherited</code> - includes members of base classes</p>
</li>
<li>
<p><code>mod_hidden</code> - includes hidden inherited members</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_boostdescribebases_hpp">&lt;boost/describe/bases.hpp&gt;</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">describe</span> <span class="p">{</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">M</span><span class="p">&gt;</span> <span class="k">using</span> <span class="n">describe_bases</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span>

<span class="p">}</span> <span class="p">}</span></code></pre>
</div>
</div>
<div class="sect3">
<h4 id="ref_describe_basest_m">describe_bases&lt;T, M&gt;</h4>
<div class="paragraph">
<p><code>M</code> must be a bitwise-or combination of <code>mod_public</code>, <code>mod_protected</code>, and
<code>mod_private</code>, and acts as a filter.</p>
</div>
<div class="paragraph">
<p><code>describe_bases&lt;T, M&gt;</code> returns <code>L&lt;D1, D2, &#8230;&#8203;, Dn&gt;</code>, where <code>L</code> is a class
template of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span><span class="o">...</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">L</span> <span class="p">{};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>and <code>Di</code> is a <em>base descriptor</em> of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">Di</span>
<span class="p">{</span>
    <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="n">modifiers</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>where <code>type</code> is the type of the base class, and <code>modifiers</code> are a bitwise-or
combination of <code>mod_public</code>, <code>mod_protected</code>, <code>mod_private</code>, and <code>mod_virtual</code>
that reflects the properties of the base class.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_boostdescribemembers_hpp">&lt;boost/describe/members.hpp&gt;</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">describe</span> <span class="p">{</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">M</span><span class="p">&gt;</span> <span class="k">using</span> <span class="n">describe_members</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span>

<span class="p">}</span> <span class="p">}</span></code></pre>
</div>
</div>
<div class="sect3">
<h4 id="ref_describe_memberst_m">describe_members&lt;T, M&gt;</h4>
<div class="paragraph">
<p><code>M</code> must be a bitwise-or combination of <code>mod_public</code>, <code>mod_protected</code>,
<code>mod_private</code>, <code>mod_static</code>, <code>mod_function</code>, <code>mod_inherited</code>, and
<code>mod_hidden</code>, and acts as a filter.</p>
</div>
<div class="paragraph">
<p><code>describe_members&lt;T, M&gt;</code> returns <code>L&lt;D1, D2, &#8230;&#8203;, Dn&gt;</code>, where <code>L</code> is a class
template of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span><span class="o">...</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">L</span> <span class="p">{};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>and <code>Di</code> is a <em>member descriptor</em> of the form</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">Di</span>
<span class="p">{</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="k">auto</span> <span class="n">pointer</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">T</span><span class="o">::</span><span class="n">m</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"m"</span><span class="p">;</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="n">modifiers</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>where <code>pointer</code> is a pointer to member (for nonstatic members) or a pointer
(for static members) identifying the class member, <code>name</code> is the name of the
member, and <code>modifiers</code> are a bitwise-or combination of <code>mod_public</code>,
<code>mod_protected</code>, <code>mod_private</code>, <code>mod_static</code>, <code>mod_function</code>, <code>mod_inherited</code>,
and <code>mod_hidden</code> that reflects the properties of the member.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_boostdescribe_hpp">&lt;boost/describe.hpp&gt;</h3>
<div class="paragraph">
<p>This convenience header includes all the headers previously
described.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="copyright">Copyright and License</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This documentation is copyright 2020 Peter Dimov and is distributed under
the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2021-03-15 17:20:31 +0200
</div>
</div>
<style>

*:not(pre)>code { background: none; color: #600000; }
:not(pre):not([class^=L])>code { background: none; color: #600000; }

</style>
</body>
</html>